package com.zhang.serviceprice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhang.internalcommon.constant.CommonStatusEnum;
import com.zhang.internalcommon.dto.ForecastPrceDTO;
import com.zhang.internalcommon.dto.PriceRule;
import com.zhang.internalcommon.dto.ResponseResult;
import com.zhang.internalcommon.response.DirectionResponse;
import com.zhang.internalcommon.response.ForecastPriceResponse;
import com.zhang.internalcommon.utils.BigDecimalUtils;
import com.zhang.serviceprice.mapper.PriceRuleMapper;
import com.zhang.serviceprice.remote.ServiceMapClient;
import com.zhang.serviceprice.service.PriceService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

@Service
public class ForecastPriceServiceImpl implements PriceService {

	@Autowired
	ServiceMapClient serviceMapClient;
	@Autowired
	private PriceRuleMapper priceRuleMapper;

	@Override
	public ResponseResult forecastPrice(String depLongitude, String depLatitude, String destLongitude, String destLatitude,String cityCode,String vehicleType) {

		ForecastPrceDTO forecastPrceDTO = new ForecastPrceDTO();
		forecastPrceDTO.setDepLongitude(depLongitude);
		forecastPrceDTO.setDepLatitude(depLatitude);
		forecastPrceDTO.setDestLongitude(destLongitude);
		forecastPrceDTO.setDestLatitude(destLatitude);
		ResponseResult<DirectionResponse> driving = serviceMapClient.driving(forecastPrceDTO);
		DirectionResponse data = driving.getData();
		Integer distance = data.getDistance();
		Integer duration = data.getDuration();

		QueryWrapper queryWrapper = new QueryWrapper();
		queryWrapper.eq("city_code",cityCode);
		queryWrapper.eq("vehicle_type",vehicleType);
		queryWrapper.orderByDesc("fare_version");
		List<PriceRule> priceRules = priceRuleMapper.selectList(queryWrapper);
		if (priceRules.isEmpty()){
			return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(),CommonStatusEnum.PRICE_RULE_EMPTY.getValue());
		}
		PriceRule priceRule = priceRules.get(0);

		Double price = getPrice(distance, duration, priceRule);
		ForecastPriceResponse forecastPriceResponse = new ForecastPriceResponse();
		forecastPriceResponse.setPrice(price);
		forecastPriceResponse.setCityCode(cityCode);
		forecastPriceResponse.setVehicleType(vehicleType);
		forecastPriceResponse.setFareType(priceRule.getFareType());
		forecastPriceResponse.setFareVersion(priceRule.getFareVersion());

		return ResponseResult.success(forecastPriceResponse);
	}

	@Override
	public ResponseResult<Double> calculatePrice(Integer distance, Integer duration, String cityCode, String vehicleType) {
		// 查询计价规则
		QueryWrapper queryWrapper = new QueryWrapper();
		queryWrapper.eq("city_code",cityCode);
		queryWrapper.eq("vehicle_type",vehicleType);
		queryWrapper.orderByDesc("fare_version");

		List<PriceRule> priceRules = priceRuleMapper.selectList(queryWrapper);
		if (priceRules.size() == 0){
			return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(),CommonStatusEnum.PRICE_RULE_EMPTY.getValue());
		}

		PriceRule priceRule = priceRules.get(0);

		// log.info("根据距离、时长和计价规则，计算价格");

		double price = getPrice(distance, duration, priceRule);
		return ResponseResult.success(price);
	}

	/**
	 * 根据距离时长计算最终价格
	 * @param distance 距离
	 * @param duration 时长
	 * @param priceRule 计算规则
	 * @return
	 */
	private Double getPrice(Integer distance, Integer duration,PriceRule priceRule) {
		// 起步价
		// BigDecimal price = new BigDecimal(0);
		double price = 0;

		Double startFare = priceRule.getStartFare();
		// BigDecimal startFareDecimal = new BigDecimal(startFare);
		// price = price.add(startFareDecimal);
		price = BigDecimalUtils.add(price,startFare);

		// 里程费
		// BigDecimal distanceDecimal = new BigDecimal(distance);
		// BigDecimal distanceMileDecimal = distanceDecimal.divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP);
		double distanceMile= BigDecimalUtils.div(distance, 1000.0);

		// 起步里程
		Double startMile = Double.valueOf(priceRule.getStartMile());
		// BigDecimal startMileDecimal = new BigDecimal(startMile);
		// double distanceSubstract = distanceMileDecimal.subtract(startMileDecimal).doubleValue();
		double distanceSubstract = BigDecimalUtils.sub(distanceMile, startMile);

		// 最终收费的里程数
		double mile = distanceSubstract < 0 ? 0 : distanceSubstract;
		// BigDecimal mileDecimal = new BigDecimal(mile).setScale(2, BigDecimal.ROUND_HALF_UP);
		// 记程单价 元/km
		Double unitPricePerMile = priceRule.getUnitPricePerMile();
		// BigDecimal unitPricePerMileDecimal = new BigDecimal(unitPricePerMile).setScale(2, BigDecimal.ROUND_HALF_UP);
		// 里程价格
		// BigDecimal mileFare = mileDecimal.multiply(unitPricePerMileDecimal).setScale(2, BigDecimal.ROUND_HALF_UP);
		double mileFare = BigDecimalUtils.mul(mile, unitPricePerMile);
		// price = price.add(mileFare);
		price += mileFare;

		// 时长费
		// BigDecimal time = new BigDecimal(duration);
		// 时长分钟数
		// BigDecimal timeDecimal = time.divide(new BigDecimal(60), 2, BigDecimal.ROUND_HALF_UP);
		double time = BigDecimalUtils.div(duration, 60.0);

		// 计时单价
		Double unitPricePerMinute = priceRule.getUnitPricePerMinute();
		// BigDecimal unitPricePerMinuteDecimal = new BigDecimal(unitPricePerMinute).setScale(2, BigDecimal.ROUND_HALF_UP);
		// 时长费用
		// BigDecimal timeFare = timeDecimal.multiply(unitPricePerMinuteDecimal).setScale(2, BigDecimal.ROUND_HALF_UP);
		double timeFare = BigDecimalUtils.mul(time, unitPricePerMinute);
		// price = price.add(timeFare);
		price += timeFare;

		BigDecimal priceDecimal = BigDecimal.valueOf(price);
		BigDecimal res = priceDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);

		return res.doubleValue();
	}

// 	public static void main(String[] args) {
// 		PriceRule priceRule = new PriceRule();
// 		priceRule.setStartMile(3);
// 		priceRule.setUnitPricePerMinute(0.5);
// 		priceRule.setUnitPricePerMile(1.8);
// 		priceRule.setStartFare(10.0);
// 		System.out.println(getPrice(6500,1800,priceRule));
// 	}
}
